元件在畫面上渲染 DOM 元素,它的生命週期可以分成三個階段:
Mount -> Update -> Unmount
對應於 Class Component,我們可以分別對應為
Function Component 沒有內容生命週期的成員函式,而是透過 useEffect
這個 Hook 為 FC 加上生命週期的概念。
前一篇介紹了可以使用 useState,藉由 State 變數改變來更新 DOM
有時候,會希望在更新 DOM 之後執行一些對應要做的處理
useEffect 就是使用在 當元件 Render 之後才執行的功能
useEffect 是一個函式,它接收二個參數。
Array
,稱為「相依陣列 (dependency list)」,它被用來做為「指定當哪些 state 和 props 被改變時,要觸發做某些事」。Function
,它用來做為「當相依陣列的變數值改變時,要對應執行的內容 (又稱為副作用)」。function MyFC({someProps}) {
useEffect(() => {
// do something when props change
}, [someProp])
}
function MyFC() {
const [state, setState] = useState('initialValue');
useEffect(() => {
// do something when state change
}, [state])
}
對應生命週期的 componentDidMount 及 componentDidUpdate,但只會在相依陣列內指定的 state or props 變更時,觸發畫面更新後才執行。
如果相依陣列為空陣列
,就只會執行一次 effect function
執行時間點為初次 Render 完成
function MyFC() {
useEffect(() => {
// run ONCE after initial rendering
}, [])
}
對應生命週期的 componentDidMount,只在初始化畫面渲染後執行
如果不帶相依陣列
,會在每次 render 完成之後都執行 effect function
function MyFC() {
useEffect(() => {
// runs after EVERY rendering
})
}
對應生命週期的 componentDidMount 及 componentDidUpdate,每次畫面渲染之後都會執行。
當元件要從畫面上被移除時,在 effection function 內,回傳一個 clean-up function
,在這個 clean-up function 中,清除在 effect function 中使用到的資源
clean-up function 對應生命週期的 componentWillUnmount,元件從畫面被移除前執行。
function MyFC() {
useEffect(() => {
// ...
return () => {
// clean-up function here
}
}, [])
}
useEffect 是在第一個 render 和隨後每一個更新之後執行。把 useEffect 想成發生在「render 之後」所觸發,而不要直接認為它就是「mount」和「update」的生命週期。 React 能保證 DOM 在執行 effect function 時已被更新。
effect function 回傳 clean-up function,有時它不只對應了 componentWillUnmount 也對應了 componentDidMount
可以發現 useEffect 是一個統整對應了 Mount
、Update
、Unmount
這三個執行流程的 API,所以相關連的功能邏輯,不用散落在每個 Lifecycle 裡,而是在一個 useEffect 寫完相關連的功能邏輯,然後用多個 useEffect 組合完成複合的功能邏輯。
在這裡先一次全部理解 useEffect 的各種組合型,接下來會用實際的範例說明使用情境,讓大家更加深對 useEffect 的用法。
https://zh-hant.reactjs.org/docs/hooks-effect.html
https://pjchender.dev/react/react-doc-hooks-into/#effect-hook
https://gcdeng.com/blog/react-hooks#effect-function